신규아이디추천

NOTE

프로그래머스(카카오) · 문자열 정제(String Normalization) 주어진 7단계 규칙을 순서대로 적용해 아이디를 정제하는 문제. 각 단계를 정규식(regex) 한 줄로 처리하면 코드가 크게 짧아진다.

📝 문제

문제에서 주어진 7단계를 그대로 순차 구현하면 된다(String Normalize Pipeline).

1. 소문자 변환
2. 허용 문자(a-z, 0-9, -, _, .) 외 제거
3. 연속된 '.'을 하나로
4. 처음/끝 '.' 제거
5. 빈 문자열이면 "a"
6. 길이 15 초과 시 15로 자르고, 끝의 '.' 제거
7. 길이 3 미만이면 마지막 문자 반복

💡 접근

핵심 정규식 패턴 4가지:

  • 허용 문자만 남기기: replaceAll("[^a-z0-9-_.]", "")^는 NOT(부정), 허용 문자 외 전부 제거.
  • 연속 dot 압축: replaceAll("[.]{2,}", ".").이 2개 이상 반복.
  • 앞뒤 dot 제거: replaceAll("^[.]|[.]$", "")^는 시작, $는 끝.
  • 길이 조정: substring으로 자르기 / while로 마지막 문자 반복.

⌨️ 풀이

private String solution(String newId) {
 
    // 1. 소문자
    newId = newId.toLowerCase();
 
    // 2. 허용 문자 외 제거
    newId = newId.replaceAll("[^a-z0-9-_.]", "");
 
    // 3. 연속된 '.' 하나로
    newId = newId.replaceAll("[.]{2,}", ".");
 
    // 4. 처음/끝 '.' 제거
    newId = newId.replaceAll("^[.]|[.]$", "");
 
    // 5. 빈 문자열이면 "a"
    if (newId.isEmpty()) {
        newId = "a";
    }
 
    // 6. 길이 15 제한 (자른 뒤 끝의 '.' 제거)
    if (newId.length() > 15) {
        newId = newId.substring(0, 15);
        newId = newId.replaceAll("[.]$", "");
    }
 
    // 7. 길이 3 미만이면 마지막 문자 반복
    while (newId.length() < 3) {
        newId += newId.charAt(newId.length() - 1);
    }
 
    return newId;
}

⏱️ 복잡도

  • 시간: O(N) — 모든 연산이 문자열 길이 기준(정규식 포함). 입력 제한이 작아 성능 여유.
  • 공간: O(N).

📎 오답 노트 (원본 코드 리뷰)

전체적으로 정답이고 논리도 깔끔했지만 다음 개선점이 있었다.

  • 문제점 1 — 잘못된 정규식: "[^a-z0-9-_.]*"처럼 *를 붙이면 빈 문자열도 매칭된다. * 없이 "[^a-z0-9-_.]"가 맞다.
  • 문제점 2 — 3단계 과잉 구현: boolean isDot 플래그로 직접 구현했는데, 연속 dot 압축은 replaceAll("[.]{2,}", ".") 한 줄로 끝난다.
  • 문제점 3 — 표준 함수 미활용: 4단계에서 newId.charAt(0) == '.' 대신 startsWith / endsWith(또는 정규식)를 쓰면 더 명확하다.

🔗 관련